#pragma once

#include "Constraint.h"

#include "Element.h"
#include "Namespace.h"
#include "ValueSpecification.h"

namespace uml {

Constraint::Constraint(const QString& umlType)
    : PackageableElement(umlType) {}

void Constraint::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    PackageableElement::fromJson(json, errorList);
    JsonSerializable::fromJsonArray(constrainedElements_, "constrainedElements", json, errorList);
    context_ = JsonSerializable::create<Namespace>(json.value("context"), errorList);

    specification_ = JsonSerializable::create<ValueSpecification>(json.value("specification"), errorList);

}

void Constraint::toJson(QJsonObject& json) {
    PackageableElement::toJson(json);
    JsonSerializable::toJsonArray(constrainedElements_, "constrainedElements", json);
    if (context_) {
        QJsonObject context_json;
        context_->toJson(context_json);
        json.insert("context", context_json);
    }
    if (specification_) {
        QJsonObject specification_json;
        specification_->toJson(specification_json);
        json.insert("specification", specification_json);
    }
}

/// <summary>
/// constrainedElements getter
/// The ordered set of Elements referenced by this Constraint.
/// </summary>
vector<shared_ptr<Element>>& Constraint::constrainedElements() {
    return constrainedElements_;
}

/// <summary>
/// context getter
/// Specifies the Namespace that owns the Constraint.
/// </summary>
shared_ptr<Namespace> Constraint::context() const {
    return context_;
}

/// <summary>
/// context setter
/// Specifies the Namespace that owns the Constraint.
/// </summary>
void Constraint::setContext(shared_ptr<Namespace> value) {
    context_ = value;
}

/// <summary>
/// specification getter
/// A condition that must be true when evaluated in order for the Constraint to be
/// satisfied.
/// </summary>
shared_ptr<ValueSpecification> Constraint::specification() const {
    return specification_;
}

/// <summary>
/// specification setter
/// A condition that must be true when evaluated in order for the Constraint to be
/// satisfied.
/// </summary>
void Constraint::setSpecification(shared_ptr<ValueSpecification> value) {
    specification_ = value;
}

} // namespace uml
